package NetWork;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

// TCP 客户端代码
public class TcpEchoClient {
    private Socket socket = null;

    public TcpEchoClient(String serverIp, int serverPort) throws IOException {
        //Socket 构造方法, 能够识别到 点分十进制 的 IP 地址 , 比 DatagramPacket 更方便
        // new 这个 对象的同时 就会 进行 TCP 连接的操作.
        // 客户端的 Socket 和 服务器端的 Socket 并不是同一个对象
        // 客户端和服务器 是一个 身份 的象征
        // 同一个程序,的身份是可能在不同的场景下发生转变
        socket = new Socket(serverIp,serverPort); // 这个 对象构造的过程 就会触发 TCP 建立连接的过程(打电话开始拨号)
        // 如果没有这个 服务器就会 accept 就会 在这里阻塞
    }

    public void start(){
        System.out.println("客户端启动!");
        Scanner scanner = new Scanner(System.in);
        try (InputStream inputStream = socket.getInputStream();
             OutputStream outputStream = socket.getOutputStream()){
            while (true) {
                // 1. 先从键盘上读取用户输入的内容
                System.out.print(":> ");
                String request = scanner.next();
                if (request.equals("exit")) {
                    System.out.println("goodbye");
                    break;
                }
                // 2. 把读到的内容构造成请求, 发送给服务器
                PrintWriter printWriter = new PrintWriter(outputStream);
                printWriter.println(request); // 获取字串
                // 此处加上一个flash 保证数据确实发送出去了
                printWriter.flush();
                // 3. 读取服务器的响应
                Scanner respScanner = new Scanner(inputStream);
                // 通过这个 respScanner 来读取数据
                String response = respScanner.next();
                // 4. 把响应内容显示到界面上
                System.out.println(response );
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) throws IOException {
        TcpEchoClient client = new TcpEchoClient("127.0.0.1",9090);
        client.start();
    }
    // 但是当前启动服务器之后
    // 先启动 客户端 1 可以看到正常的上线显示
    // 再启动 客户端 2 就没有看到任何的提示
    // 这时候 客户端1 进行发送消息都很正常
    // 但是 客户端 2 发送消息是不能够的
    //  这是因为 服务器端正在被占用着
    // 之后客户端1退出之后 客户端2才能正常使用
    // 这是因为 服务器端 代码这里 processConnection 的方法中,当有客户端连上服务器之后,就会执行到这个方法的 while 循环当中
    // 所以 只要 while 这个循环不结束 这个方法也就不会结束
    // 进一步也就无法第二次的调用 accept
    // 但是这个方法中是不能够不使用循环的
    // 所以没法快速调用到 accept 就没法使用多个客户端
    // 解决方法 就是 在服务器客户端当中  使用多线程!
    // 具体做法就是
    // 主线程 专门负责进行accept
    // 每次收到一个连接,创建一个新线程,由这个新线程负责处理这个新的客户端
}
